package com.fingard.dsp.bank.directbank.bocz01;

import java.util.Calendar;
import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.bankInterface.ITransaction;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7515TodayTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.Req7516HisTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.RetAtsTrans;
import com.fingard.dsp.bank.reqrespobj.transaction.detail.RetAtsTransDetail;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

public class BOCZ01Transaction extends BOCZ01Base implements ITransaction {

    //采用流处理方式
    //1、循环调用readRecord()读取一个请求明细，然后写入发银行的XML对象
    //2、发银行
    //3、循环调用XmlTextReader.read()读取一个银行返回节点，赋值返回ATS的明细对象，
    //   然后调用writeRetDetail()，写入返回ATS的明细
    public RetAtsTrans d_7516_HisTrans(Req7516HisTrans p_req7516) throws Exception {
        //历史明细查询返回ATS的对象
        RetAtsTrans retAts = new RetAtsTrans(p_req7516.reqHeader);
        String tmpRespCode = "";
        String tmpRespInfo = "";
        retAts.writeStart();//写返回ATS的统一头部信息
        try {
            serviceId = "CBE010102";
            serialNo = p_req7516.reqHeader.transSeqID;
            //模拟返回前9天的数据 之后删除

            //tmpClndrStepTo.get(Calendar.MONTH) MONTH是从0开始编的，意味着0是1月，11是12月
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_req7516.getDateFrom());

            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_req7516.getDateTo());


            int tmpNowStartRecord = 0;//总条数
            int turnPageBeginPos = 1;//翻页数据起始位置
            int turnPageShowNum = 50;//翻页一次显示数量 默认50
            int tmpNowReadedCount = 0;//已读条数

            boolean tmpQryNext = true;
            while (tmpQryNext && tmpRespCode.length() == 0) {//分页查询
                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                //写入通用的头部节点
                writeCommonHeader(xmlWriter);
                xmlWriter.writeStartElement("ReqParam");
                xmlWriter.writeElementString("accountNo", p_req7516.actNum);
                xmlWriter.writeElementString("turnPageBeginPosTemp", String.valueOf(turnPageBeginPos));//翻页数据起始位置
                xmlWriter.writeElementString("turnPageShowNum", String.valueOf(turnPageShowNum));//翻页一次显示数量 默认50
                xmlWriter.writeElementString("beginDate", Format.Date8Format.format(tmpCalendarFrom.getTime()));
                xmlWriter.writeElementString("endDate", Format.Date8Format.format(tmpCalendarTo.getTime()));
                xmlWriter.writeElementString("transferDirection", "");
                xmlWriter.writeElementString("beginAmt", "");
                xmlWriter.writeElementString("endAmt", "");
                xmlWriter.writeEndElement();
                xmlWriter.writeEndDocument();
                String dataConvert = xmlWriter.toXmlString();
                int index = dataConvert.indexOf("?>");
                String data = dataConvert.substring(0, index + 2) + "\r\n" + clearLineWrapAndBlank(dataConvert.substring(index + 2));
                //发送给银行的签名端口进行签名
                String[] tmpSign = sendToBankSignXml(data);
                if (tmpSign[0].length() == 0) {
                    String body = "";
                    String aa = "<result>";
                    int i = tmpSign[1].indexOf(aa);
                    if (i != -1) {
                        body = tmpSign[1].substring(i + 8, i + 9);
                    }
                    if ("0".equals(body)) {
                        String ab = "<sign>";
                        String ac = "</sign>";
                        int ib = tmpSign[1].indexOf(ab);
                        int ic = tmpSign[1].indexOf(ac);
                        //以下为最终的签名结果
                        signature = clearLineWrapAndBlank(tmpSign[1].substring(ib + 6, ic));
                        String[] tmpStrRet = sendToBank(data);
                        XmlTextReader tmpBkReader;
                        //模拟银行返回
                /*tmpStrRet[0]="";
                tmpStrRet[1]="00218000000||#<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                        "<BankData>\n" +
                        "<opRep>\n" +
                        "<opResult>\n" +
                        "<retCode>000000</retCode>\n" +
                        "<retMessage></retMessage>\n" +
                        "<turnPageTotalNum>2</turnPageTotalNum>\n" +
                        "<list>\n" +
                        "<row>"+
                        "<transferDate>20170825</transferDate>"+
                        "<vouchersNo></vouchersNo>"+
                        "<0recAccount>2222222555555</0recAccount>"+
                        "<recAccountName></recAccountName>"+
                        "<recAccountOpenNo></recAccountOpenNo>"+
                        "<transferTime>20170825125022</transferTime>"+
                        "<loanFlag>D</loanFlag>"+
                        "<transferSum>11.00</transferSum>"+
                        "<Balance>1234.00</Balance>"+
                        "<currencyType>CNY</currencyType>"+
                        "</row>"+
                        "<row>"+
                        "<transferDate>20170825</transferDate>"+
                        "<vouchersNo></vouchersNo>"+
                        "<0recAccount>2222222555555</0recAccount>"+
                        "<recAccountName></recAccountName>"+
                        "<recAccountOpenNo></recAccountOpenNo>"+
                        "<transferTime>20170825115025</transferTime>"+
                        "<loanFlag>C</loanFlag>"+
                        "<transferSum>22.00</transferSum>"+
                        "<Balance>1246.00</Balance>"+
                        "<currencyType>CNY</currencyType>"+
                        "</row>"+
                        "</list>"+
                        "</opResult>\n" +
                        "</opRep>\n" +
                        "</BankData>";*/
                        if (tmpStrRet[0].length() == 0) {
                            StringBuilder tmpSbMsg = new StringBuilder();
                            tmpBkReader = loadBankRespXmlReader(tmpStrRet[1].substring(tmpStrRet[1].indexOf("#") + 1), tmpSbMsg);
                            if (tmpBkReader != null) {
                                String retCode = tmpBkReader.getFirstText("/BankData/opRep/opResult/retCode");
                                String errorMsg = tmpBkReader.getFirstText("/BankData/opRep/opResult/retMessage");
                                if (isActiveRetCode(retCode)) {
                                    int tmpTotalRocords = 0;//总条数
                                    if (tmpBkReader.getFirstText("/BankData/opRep/opResult/turnPageTotalNum") != null && tmpBkReader.getFirstText("/BankData/opRep/opResult/turnPageTotalNum").trim().length() > 0) {
                                        tmpTotalRocords = Integer.parseInt(tmpBkReader.getFirstText("/BankData/opRep/opResult/turnPageTotalNum"));
                                    }
                                    int tmpEachPiCount = 0;
                                    while (tmpBkReader.read("/BankData/opRep/opResult/list/row")) {
                                        tmpEachPiCount++;
                                        RetAtsTransDetail tmpRetDetail = new RetAtsTransDetail();
                                        tmpRetDetail.recAccBank = tmpBkReader.readedXElement.getSingleText("recAccountOpenBank");
                                        tmpRetDetail.recAccNum = tmpBkReader.readedXElement.getSingleText("recAccount");
                                        tmpRetDetail.recAccName = tmpBkReader.readedXElement.getSingleText("recAccountName");
                                        tmpRetDetail.cur = convertCurToATS(tmpBkReader.readedXElement.getSingleText("currencyType"));
                                        String creditDebitFlag = tmpBkReader.readedXElement.getSingleText("loanFlag");//D支出 C收入
                                        String tranAmount = tmpBkReader.readedXElement.getSingleText("transferSum");
                                        if (creditDebitFlag != null) {
                                            if ("D".equals(creditDebitFlag)) // 原先是D 借贷标识
                                            {
                                                if (tranAmount.indexOf("-") >= 0) {
                                                    tmpRetDetail.cdFlag = "2";
                                                } else {
                                                    tmpRetDetail.cdFlag = "1";
                                                }
                                            } else if ("C".equals(creditDebitFlag)) {
                                                if (tranAmount.indexOf("-") >= 0) {
                                                    tmpRetDetail.cdFlag = "1";
                                                } else {
                                                    tmpRetDetail.cdFlag = "2";
                                                }
                                            } else {
                                                tmpRespCode = "-1";
                                                tmpRespInfo = "借贷标志( " + creditDebitFlag + ")无法识别，请与银行核对";
                                                retAts = new RetAtsTrans(p_req7516.reqHeader);
                                                retAts.writeStart();//写返回ATS的统一头部信息
                                                retAts.writeRespCode(tmpRespCode);
                                                retAts.writeRespInfo(tmpRespInfo);
                                                retAts.writeEnd();
                                                return retAts;
                                            }
                                        }
                                        tmpRetDetail.tranAmt = tranAmount.replace("-", "");
                                        tmpRetDetail.accBal = tmpBkReader.readedXElement.getSingleText("balance").trim();//余额

                                        String tranDate = tmpBkReader.readedXElement.getSingleText("transferDate");//yyyyMMdd 系统格式为yyyy-MM-dd hh:mm:ss
                                        String transferTime = tmpBkReader.readedXElement.getSingleText("transferTime");//HHmmss
                                        transferTime = transferTime.substring(0, 2) + ":" + transferTime.substring(2, 4) + ":" + transferTime.substring(4);
                                        tmpRetDetail.tranDate = tranDate.substring(0, 4) + "-" + tranDate.substring(4, 6) + "-" + tranDate.substring(6);
                                        tmpRetDetail.tranTime = tmpRetDetail.tranDate + " " + transferTime;
                                        tmpRetDetail.valueDate = tmpRetDetail.tranDate;////起息日没有返回就用交易日
                                        tmpRetDetail.usage = tmpBkReader.readedXElement.getSingleText("resume");
                                        tmpRetDetail.abstr = pickupAbstr(tmpRetDetail.usage);
                                        if (StringHelper.isNullOrEmpty(tmpRetDetail.actNum)) {
                                            tmpRetDetail.actNum = p_req7516.actNum;
                                        }
                                        retAts.writeRetDetail(tmpRetDetail);
                                    }
                                    tmpNowReadedCount += tmpEachPiCount;//总记录数
                                    if (tmpNowReadedCount < tmpTotalRocords)//查询下一页
                                    {
                                        turnPageBeginPos = turnPageBeginPos + turnPageShowNum;//改变起始位置查询下一页
                                    } else if (tmpNowReadedCount == tmpTotalRocords)//本次分页查询完毕
                                    {
                                        tmpQryNext = false;
                                        tmpNowReadedCount = 0;
                                        continue;
                                    }
                                } else {
                                    tmpQryNext = false;
                                    tmpRespCode = "-1";
                                    tmpRespInfo = errorMsg;
                                    break;
                                }
                            } else {
                                tmpQryNext = false;
                                tmpRespCode = "-1";
                                tmpRespInfo = tmpSbMsg.toString();
                                break;
                            }
                        } else {
                            tmpQryNext = false;
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpStrRet[1];
                            break;
                        }
                    } else {//签名数据返回数据为空
                        tmpRespCode = "-1";
                        tmpRespInfo = tmpSign[1];
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = tmpSign[1];
                }
            }
        } catch (Exception e) {
            tmpRespCode = "-1";
            tmpRespInfo = e.getMessage();
            e.printStackTrace();
        }
        if ("-1".equals(tmpRespCode)) {
            retAts = new RetAtsTrans(p_req7516.reqHeader);
            retAts.writeStart();//写返回ATS的统一头部信息
            retAts.writeRespCode(tmpRespCode);
            retAts.writeRespInfo(tmpRespInfo);
        } else if (retAts.getWrittenRdCount() == 0) {
            retAts.writeRespCode("0");
            retAts.writeRespInfo("交易为空");
        }
        retAts.writeEnd();
        return retAts;
    }

    //当日明细查询调用历史明细查询方法
    public RetAtsTrans d_7515_TodayTrans(Req7515TodayTrans p_req7515) throws Exception {
        Req7516HisTrans tmpReq7516 = new Req7516HisTrans(p_req7515.reqHeader);
        tmpReq7516.actArea = p_req7515.actArea;
        tmpReq7516.actCur = p_req7515.actCur;
        tmpReq7516.actNum = p_req7515.actNum;
        String tmpStrToday = Format.Date8Format.format(new Date());
        tmpReq7516.dateFrom = tmpStrToday;
        tmpReq7516.dateTo = tmpStrToday;
        return d_7516_HisTrans(tmpReq7516);
    }
}
